//=============================================================================
//
//   Copyright (C) 2020 All rights reserved.
//
//   Filename:		vtu_writer.rs
//
//   Author: Wang Zhecheng - wangzhecheng@yeah.net
//
//   Date: 2020-10-10 01:15
//
//   Last Editors: Wang Zhecheng - wangzhecheng@yeah.net
//
//   Last modified:	2020-11-03 22:19
//
//   Description:
//
//=============================================================================
use crate::util::ObserverLike;
use std::fs;
use std::path::PathBuf;
use xml::writer::{EmitterConfig, XmlEvent};

///
///
///
pub struct VTUWriter {
    dir: PathBuf,
    name: PathBuf,
    pvd: fs::File,
    count1: usize,
}

impl ObserverLike for VTUWriter {
    fn update(&mut self) {
        let name = self
            .name
            .to_str()
            .expect("Failed to convert project name in vtu_writer to str")
            .to_string()
            + "_"
            + self.count1.to_string().as_str()
            + ".vtu";
        self.count1 += 1;
        let vtu = fs::File::create(self.dir.join(name)).expect("Failed to create vtu file");
        let mut w = EmitterConfig::new()
            .perform_indent(true)
            .create_writer(&vtu);
        unwrap_all! {
            w.write(XmlEvent::start_element("VTKFile")
                    .attr("type", "UnstructuredGrid")
                    .attr("version", "0.1")
                    .attr("byte_order","LittleEndian"));
            w.write(XmlEvent::start_element("UnstructuredGrid"));
                w.write(XmlEvent::start_element("Piece"));
                w.write(XmlEvent::end_element());
                w.write(XmlEvent::start_element("Cells"));
                w.write(XmlEvent::end_element());
                w.write(XmlEvent::start_element("PointData"));
                w.write(XmlEvent::end_element());
                w.write(XmlEvent::start_element("CellData"));
                w.write(XmlEvent::end_element());
            w.write(XmlEvent::end_element());
            w.write(XmlEvent::end_element())
        }
    }
}

impl VTUWriter {
    pub fn from_path(path: PathBuf) -> Self {
        let dir = if path.is_dir() {
            path.to_path_buf()
        } else {
            path.parent()
                .expect("Failed to get parent path")
                .to_path_buf()
        };
        let name = PathBuf::from(path.file_stem().expect("Failed to get file stem from path"));
        let pvd = fs::File::create(dir.join(&name).with_extension("pvd"))
            .expect("Failed to create pvd file");
        // clear
        clear_directory(dir.clone());
        let mut w = EmitterConfig::new()
            .perform_indent(true)
            .create_writer(&pvd);
        unwrap_all! {
            w.write(XmlEvent::start_element("VTKFile")
                    .attr("type", "Collection")
                    .attr("version", "0.1")
                    .attr("byte_order","LittleEndian")
                    .attr("compressor", "vtkZLibDataCompressor"));
            w.write(XmlEvent::end_element())
        }
        Self {
            dir,
            name,
            pvd,
            count1: 0,
        }
    }

    ///
    /// private methods
    ///
    fn create_vtu(&self) {}
}

fn clear_directory(path: PathBuf) {
    for entry in path
        .read_dir()
        .expect("Failed to read directory")
        .filter(|s| s.as_ref().unwrap().path().extension().unwrap() == "vtu")
    {
        std::fs::remove_file(entry.unwrap().path()).expect("Failed to delete file");
    }
}

#[test]
fn pvd_test() {
    let mut writer = VTUWriter::from_path(PathBuf::from("example/example.json"));
    // writer.init();
    writer.update();
    writer.update();
}
